|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
(Publisher: John Wiley & Sons, Inc.)
Author(s): Rod Stephens
ISBN: 0471323519
Publication Date: 11/01/98
Part Two Coding Style
Many of the coding guidelines in the following chapters are designed to steer developers away from buggy situations. Some make certain kinds of bugs less likely to occur. Others make bugs easier to find when they do occur.
Several of these suggestions forbid anachronistic syntax. Deftype statements, for instance, are a throwback to older versions of Basic and Fortran that allowed only very short variable names. When variables could only be six characters long, it made sense to use initial letters to indicate data type. For example, all variables with names starting with H, I, or J were integers.
Modern Visual Basic allows variable names to be much longer so this practice is no longer necessary. It can also cause confusion, so the guidelines that follow recommend that you do not use Deftype statements.
Other guidelines are meant to remove ambiguity from what might otherwise be confusing situations. At times these rules appear as arbitrary dictates that stifle creativity. Coding requires creativity, but reading code should not. If the code is hard to read, it will be harder for developers to find and remove bugs. It will also be more likely that bug fixes will introduce new bugs.
Standardizing certain naming conventions and coding practices can make reading the code easier. For example, if every developer names global variables with LeadingCapitals, you can easily tell whether a variable is global or not. This small reduction in artistic license can make the code much easier to understand.
With this type of suggestion, consistency is more important than the exact details. It does not matter whether you use LeadingCapitals, initialLowercaseAndCapitals, or Leading_Capitals_With_Underscores to represent global variables as long as every developer follows the same standards. If you do not like one of these stylistic rules, change it. Just make sure everyone agrees on the new style.
CHAPTER 3 Variables
This chapter explains methods for declaring and using variables that can prevent bugs. Most of the rules are extremely simple. Once you have become accustomed to them, they are very easy to follow.
The exact details of some of these rules are unimportant as long as all developers follow the same practices. For example, Hungarian notation improves readability, but which characters you use to denote specific data types does not matter. You can use any combination of characters you like. In fact, when you create new classes and user-defined data types, you should invent new abbreviations to use with Hungarian notation.
The power of these guidelines comes from consistent use. Every member of the team must follow them at all times. Breaking the rules even occasionally can have disastrous consequences. For example, if most of the team avoids variant data types, they will come to expect certain kinds of behavior in expressions. If one programmer uses variants extensively, the others may be confused. They may expect a statement to behave one way when it actually does something else.
Explicitly Declare Variables
Explicitly declare all variables on separate lines. If you do not declare a variable, Visual Basic assumes it is a variant. If you leave off the variables data type, Visual Basic also assumes it is a variant. For example, the following statement declares a variant named count.
Dim count
To avoid ambiguity, always declare variables with their data types, even if the variable is a variant.
Dim count As Variant
Declare each variable on a separate line. Many programmers, especially those experienced with another language, try to declare multiple variables on one line like this:
Dim A, B, C As Integer
In Visual Basic, the data type part of a declaration only applies to the immediately preceding variable. All the other variables are assigned the default data type variant. In this case, the code declares variable C as an integer, and variables A and B as variants.
Usually this declaration is a mistake and all of the variables are intended to be integers. The single-line declaration should be rewritten as
Dim A As Integer, B As Integer, C As Integer
If the author of the code understands the original declaration and really wants to create two variants and an integer, someone reading the code later may be confused. Even if he understands what the declaration actually does, he may not be sure the original author understood correctly. He may change the declaration into an incorrect one trying to fix a problem that is not there. Prevent this confusion by explicitly declaring all variables with their data types, even variants.
To make it easier for the reader to find all of the variable declarations, put each on a separate line. Place them all at the beginning of the routine or module in which they are declared.
Dim A As Variant
Dim B As Variant
Dim C As Integer
Use Option Explicit
Normally when Visual Basic sees a variable it does not recognize, it silently creates the variable. This allows the code to create variables as they are needed without explicitly declaring them. For example, the following code is a valid Visual Basic subroutine.
Private Sub CountTo10()
For i = 1 To 10
Debug.Print Format$(i)
Next i
End Sub
One advantage to automatic variable creation is that variables that are not used are not created. For example, suppose a subroutine uses the variable tmp in an intermediate calculation. Suppose the routine is later modified so it does not use tmp anymore. If tmp is explicitly declared and the declaration is not removed, the routine still allocates memory for tmp even though it is unused. Implicit variable declaration prevents this problem.
Unfortunately, implicit variable declaration often causes some much more subtle problems. Consider the following function:
Public Function Factorial(num As Long) As Long
factorial_value = 1
For i = 1 To num
factorial_value = i * factorial_valeu
Next i
Factorial = factorial_value
End Sub
When it reaches the first line in the function, Visual Basic sees the variable factorial_value. Since it has not seen this variable before, it automatically allocates memory for it. Initially, that variable is initialized with the value 0.
When the program reaches the third line, it sees the misspelling factorial_valeu. Visual Basic has not seen this name before, so it assumes this is a new variable. It automatically allocates memory for factorial_valeu and initializes its value to 0. This variable is never assigned a new value, so it always remains 0.
The program then sets factorial_value equal to itself times factorial_valeu. Since factorial_valeu always equals 0, factorial_value is set to 0. Eventually, the function returns the value stored in factorial_value, which is always 0.
Finding the bug in this function could be very frustrating. The code looks fine to Visual Basic, so it will not report an error. The only way to solve the problem is to walk through the code and stare at it until you see the typographical error.
You can prevent this sort of error by starting all modules with the following statement:
Option Explicit
When a module begins with the Option Explicit statement, Visual Basic generates an error whenever it sees a variable that has not yet been declared. In the following code, Visual Basic immediately complains about the undeclared variable factorial_valeu. Instead of hiding the problem and causing an obscure bug, the system makes the problem obvious.
Option Explicit
Public Function Factorial(num As Long) As Long
Dim factorial_value As Long
factorial_value = 1
For i = 1 To num
factorial_value = i * factorial_valeu
Next i
Factorial = factorial_value
End Sub
Note that Option Explicit does not require that you explicitly declare data types for variables. You still need to do that yourself. The following code is valid, although it would be better to explicitly declare factorial_values data type as in the previous example.
Option Explicit
Public Function Factorial(num As Long) As Long
Dim factorial_value
factorial_value = 1
For i = 1 To num
factorial_value = i * factorial_value
Next i
Factorial = factorial_value
End Sub
|